package com.crystal.jcms.utils;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlpull.v1.XmlPullParser;
import com.crystal.jcms.soap.SoapUtils;

import android.R.string;
import android.content.Context;
import android.util.Xml;

public class RequestUtils {

	public interface CallBack {
		void onRequestComplete(String result);
	}

	public static void doPostAsyn(final Context context, final String xmlName, final String method,
			final Map<String, String> params, final CallBack callback) {
		new Thread(new Runnable() {
			public void run() {
				String strResult = "";
				try {
					String soap = readSoapFile(xmlName, params);
					strResult = SendRequestToServer(context, soap, method);
				} catch (Exception e) {
					strResult = "500_"+e.getMessage();
				}
				if (callback != null) {
					callback.onRequestComplete(strResult);
				}
			}
		}).start();
	}

	public static String doPost(Context context, String xmlName, String method, Map<String, String> params) {
		String strResult = "";
		try {
			String soap = readSoapFile(xmlName, params);
			strResult = SendRequestToServer(context, soap, method);
		} catch (Exception e) {
			strResult = "500_"+e.getMessage();
		}
		return strResult;
	}

	/**
	 * 向服务器发送请求
	 * 
	 * @param soap
	 * @return
	 * @throws Exception
	 */
	public static String SendRequestToServer(Context context, String soap, String method) throws Exception {

		String strResult = null;
		if (!NetUtils.isConnected(context)) {
			strResult = "500_网络异常!";
			return strResult;
		}
		byte[] entity = soap.getBytes();
		String serverUrl = SpUtils.get(context, "ServerUrl", "").toString();
		// 根据地址创建URL对象
		URL url = new URL(serverUrl + "/shpz/Shpz.asmx");
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		// int code=conn.getResponseCode();
		conn.setRequestMethod("POST");
		conn.setConnectTimeout(5000);
		conn.setDoOutput(true); // 设置是否可以写入数据
		conn.setRequestProperty("Content-Type", "application/soap+xml;charset=utf-8");
		conn.setRequestProperty("Content-Length", String.valueOf(entity.length));
		// 获取输出流
		OutputStream os = conn.getOutputStream();
		os.write(entity);
		os.flush();
		if (conn.getResponseCode() == 200) {
			// 获取响应的输入流对象
			return parseResponseXML(conn.getInputStream(), method);
		} else {
			strResult = "500_请求异常!";
		}
		return strResult;
	}

	/**
	 * 替换文件中占位符
	 * 
	 * @param xml
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String replace(String xml, Map<String, String> params) throws Exception {
		String result = xml;
		if (params != null && !params.isEmpty()) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				String name = "\\$" + entry.getKey();
				Pattern pattern = Pattern.compile(name);
				Matcher matcher = pattern.matcher(result);
				if (matcher.find()) {
					result = matcher.replaceAll(entry.getValue());
				}
			}
		}
		return result;
	}

	/**
	 * 读取流信息
	 * 
	 * @param xmlName
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public static String readSoapFile(String xmlName, Map<String, String> params) throws Exception {
		InputStream inStream = SoapUtils.class.getResourceAsStream(xmlName);
		byte[] data = StreamUtil.InputStreamToBytes(inStream);
		String soapXml = new String(data);
		return replace(soapXml, params);
	}

	/**
	 * 解析XML文件
	 * 
	 * @param inStream
	 * @return
	 * @throws Exception
	 */
	public static String parseResponseXML(InputStream inStream, String methodName) throws Exception {
		methodName = methodName + "Result";
		XmlPullParser pullParser = Xml.newPullParser();
		pullParser.setInput(inStream, "utf-8");
		int eventType = pullParser.getEventType();
		while (eventType != XmlPullParser.END_DOCUMENT) {
			switch (eventType) {
			case XmlPullParser.START_TAG:
				if (methodName.equals(pullParser.getName())) {
					String result = pullParser.nextText();
					return result;
				}
				break;
			}
			eventType = pullParser.next();
		}
		return null;
	}
}
